package libs

import (
	"errors"
	"fmt"
	"log"
	"net"
)

type HostInfo struct {
	IP       string
	Port     int
	SSLPort  int
	Site     string
	SSLSite  string
	IpaPath  string
	IconPath string
}

// SSLPortNum 监听端口号，暂写在代码中
const SSLPortNum = 5433

// PortNum 监听端口号，暂写在代码中
const PortNum = 8888

func NewHostInfo() (*HostInfo, error) {
	hostinfo := HostInfo{}

	ip, err := externalIP()
	if err != nil {
		log.Println(err)
		return &hostinfo, err
	}

	hostinfo.IP = ip.String()
	hostinfo.SSLPort = SSLPortNum
	hostinfo.Port = PortNum
	hostinfo.Site = fmt.Sprintf("http://%s:%d", hostinfo.IP, hostinfo.Port)
	hostinfo.SSLSite = fmt.Sprintf("https://%s:%d", hostinfo.IP, hostinfo.SSLPort)
	hostinfo.IpaPath = hostinfo.SSLSite + "/static/ios.ipa"
	hostinfo.IconPath = hostinfo.SSLSite + "/static/icon.png"

	return &hostinfo, nil
}

func externalIP() (net.IP, error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, iface := range ifaces {
		if iface.Flags&net.FlagUp == 0 {
			continue // interface down
		}
		if iface.Flags&net.FlagLoopback != 0 {
			continue // loopback interface
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return nil, err
		}
		for _, addr := range addrs {
			ip := getIpFromAddr(addr)
			if ip == nil {
				continue
			}
			return ip, nil
		}
	}
	return nil, errors.New("connected to the network?")
}

func getIpFromAddr(addr net.Addr) net.IP {
	var ip net.IP
	switch v := addr.(type) {
	case *net.IPNet:
		ip = v.IP
	case *net.IPAddr:
		ip = v.IP
	}
	if ip == nil || ip.IsLoopback() {
		return nil
	}
	ip = ip.To4()
	if ip == nil {
		return nil // not an ipv4 address
	}
	return ip
}
